package com.jingdianjichi.wx.ai;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.*;
import lombok.RequiredArgsConstructor;
import okhttp3.*;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.Duration;

/**
 * SiliconFlowClient类
 * 这是一个用于与SiliconFlow API交互的客户端组件
 * 使用了Spring框架的@Component注解进行标记
 * 通过@RequiredArgsConstructor注解实现了依赖注入
 */
@Component
@RequiredArgsConstructor
public class SiliconFlowClient {
    // SiliconFlowProperties属性，用于存储API配置信息
    private final SiliconFlowProperties props;
    // ObjectMapper实例，用于JSON序列化和反序列化
    private final ObjectMapper mapper = new ObjectMapper();
    // OkHttpClient实例，用于HTTP请求
    private OkHttpClient http;

    /**
     * 获取OkHttpClient实例的懒加载方法
     * 如果http实例为null，则创建一个新的OkHttpClient实例
     * 设置了调用超时时间为配置中指定的毫秒数
     * @return OkHttpClient实例
     */
    private OkHttpClient http() {
        if (http == null) {
            http = new OkHttpClient.Builder()
                    .callTimeout(Duration.ofMillis(props.getTimeoutMillis()))
                    .build();
        }
        return http;
    }

    /**
     * 发送一次聊天请求的方法
     * @param userText 用户输入的文本
     * @return API返回的回复文本
     * @throws IOException 如果发生I/O错误或API返回错误
     */
    public String chatOnce(String userText) throws IOException {
        // 创建JSON请求根节点
        ObjectNode root = mapper.createObjectNode();
        // 设置模型名称
        root.put("model", props.getModel());
        // 创建消息数组
        ArrayNode messages = root.putArray("messages");
        // 添加用户消息
        messages.add(msg("user", userText));
        // 设置温度参数
        root.put("temperature", props.getTemperature());
        // 设置最大令牌数
        root.put("max_tokens", props.getMaxTokens());
        // 设置不使用流式响应
        root.put("stream", false);

        // 构建HTTP请求
        Request req = new Request.Builder()
                .url(props.getBaseUrl() + "/chat/completions") // 设置请求URL
                .addHeader("Authorization", "Bearer " + props.getApiKey()) // 添加认证头
                .addHeader("Content-Type", "application/json") // 设置内容类型
                .post(RequestBody.create(root.toString(), MediaType.parse("application/json"))) // 设置请求体
                .build();

        // 执行请求并处理响应
        try (Response resp = http().newCall(req).execute()) {
            // 检查响应是否成功
            if (!resp.isSuccessful()) throw new IOException("HTTP " + resp.code() + ": " + resp.message());
            // 获取响应体
            String body = resp.body() != null ? resp.body().string() : "";
            // 解析JSON响应
            JsonNode json = mapper.readTree(body);
            // 获取choices节点
            JsonNode choices = json.path("choices");
            // 如果choices存在且非空，返回第一个选择的消息内容
            if (choices.isArray() && choices.size() > 0) {
                return choices.get(0).path("message").path("content").asText("");
            }
            return "";
        }
    }

    /**
     * 创建消息节点的辅助方法
     * @param role 消息角色（如"user"、"assistant"等）
     * @param content 消息内容
     * @return 包含角色和内容的ObjectNode
     */
    private ObjectNode msg(String role, String content) {
        ObjectNode o = mapper.createObjectNode();
        o.put("role", role);
        o.put("content", content == null ? "" : content);
        return o;
    }
}
